{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Linear Regression Example\n",
    "\n",
    "A linear regression learning algorithm example using TensorFlow library.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "import numpy\n",
    "import matplotlib.pyplot as plt\n",
    "import time\n",
    "rng = numpy.random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Parameters\n",
    "learning_rate = 0.01\n",
    "training_epochs = 1000\n",
    "display_step = 50"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Training Data\n",
    "train_X = numpy.asarray([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167,\n",
    "                         7.042,10.791,5.313,7.997,5.654,9.27,3.1])\n",
    "train_Y = numpy.asarray([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221,\n",
    "                         2.827,3.465,1.65,2.904,2.42,2.94,1.3])\n",
    "n_samples = train_X.shape[0]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7fb607e21e10>]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fb5a9d0ce90>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#show data\n",
    "plt.plot(train_X, train_Y, 'ro', label='Original data')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Learn a linear regression to fit the dataset\n",
    "y_pred = w*x+b\n",
    "\n",
    "We learn w and b from the dataset"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Two phase to write your tf program\n",
    "### Build a model (assemble a graph)\n",
    "1. Define placeholders for input and output (label)\n",
    "2. Define the weight\n",
    "3. Define the inference model\n",
    "4. Define loss function\n",
    "5. Define optimizer\n",
    "\n",
    "### Training (Use a session to execute operations in the graph)\n",
    "1. Initialize model parameters\n",
    "2. Input training data\n",
    "3. Execute inference model on training data\n",
    "4. Compute loss\n",
    "5. Adust mode parameters to minimize the loss\n",
    "6. Repeat 2->5 util loss convergence\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### linear regression v1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.summary.writer.writer.FileWriter at 0x7fb5aa7f2450>"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "# define the input by placeholder\n",
    "with tf.name_scope('inputs'):\n",
    "    x = tf.placeholder(tf.float32,name='x')\n",
    "    y = tf.placeholder(tf.float32,name='y')\n",
    "# define the weight\n",
    "# represent the learnable paramters by tf.placeholder\n",
    "with tf.variable_scope('params'):\n",
    "    w = tf.placeholder(tf.float32,name='w')\n",
    "    b = tf.placeholder(tf.float32,name='b')\n",
    "# construct inference model\n",
    "with tf.name_scope('inference'):\n",
    "    y_pred = tf.multiply(w,x) + b\n",
    "# Mean squared error as loss function\n",
    "with tf.name_scope('loss'):\n",
    "    cost = tf.reduce_sum(tf.pow(y_pred-y, 2))/(2*n_samples)\n",
    "with tf.name_scope('grads'):\n",
    "    grad_w,grad_b = tf.gradients(cost,[w,b])\n",
    "tf.summary.FileWriter('linear_model_v1',tf.get_default_graph())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 0050 cost= 0.014461425 W= 0.145537480712 b= 1.55003869534\n",
      "Epoch: 0100 cost= 0.013435257 W= 0.151726171374 b= 1.50551772118\n",
      "Epoch: 0150 cost= 0.012504579 W= 0.157546773553 b= 1.46364462376\n",
      "Epoch: 0200 cost= 0.011659737 W= 0.163021221757 b= 1.4242619276\n",
      "Epoch: 0250 cost= 0.010892101 W= 0.168170064688 b= 1.38722145557\n",
      "Epoch: 0300 cost= 0.010193979 W= 0.173012688756 b= 1.35238397121\n",
      "Epoch: 0350 cost= 0.009558465 W= 0.17756728828 b= 1.31961846352\n",
      "Epoch: 0400 cost= 0.008979419 W= 0.181851029396 b= 1.28880167007\n",
      "Epoch: 0450 cost= 0.008451318 W= 0.185879975557 b= 1.25981760025\n",
      "Epoch: 0500 cost= 0.007969234 W= 0.189669311047 b= 1.23255753517\n",
      "Epoch: 0550 cost= 0.007528737 W= 0.193233266473 b= 1.20691859722\n",
      "Epoch: 0600 cost= 0.007125868 W= 0.196585267782 b= 1.1828045845\n",
      "Epoch: 0650 cost= 0.006757063 W= 0.199737906456 b= 1.16012465954\n",
      "Epoch: 0700 cost= 0.006419138 W= 0.202703043818 b= 1.13879370689\n",
      "Epoch: 0750 cost= 0.006109224 W= 0.205491825938 b= 1.11873137951\n",
      "Epoch: 0800 cost= 0.005824737 W= 0.208114758134 b= 1.0998622179\n",
      "Epoch: 0850 cost= 0.005563359 W= 0.210581675172 b= 1.08211541176\n",
      "Epoch: 0900 cost= 0.005323000 W= 0.212901875377 b= 1.06542396545\n",
      "Epoch: 0950 cost= 0.005101782 W= 0.215084090829 b= 1.04972529411\n",
      "Epoch: 1000 cost= 0.004898002 W= 0.217136517167 b= 1.03496026993\n",
      "Optimization Finished, spend time: 9.67348790169!\n",
      "{<tf.Tensor 'params/w:0' shape=<unknown> dtype=float32>: 0.21713652121989271, <tf.Tensor 'params/b:0' shape=<unknown> dtype=float32>: 1.034960279819704, <tf.Tensor 'inputs/x:0' shape=<unknown> dtype=float32>: array([  3.3  ,   4.4  ,   5.5  ,   6.71 ,   6.93 ,   4.168,   9.779,\n",
      "         6.182,   7.59 ,   2.167,   7.042,  10.791,   5.313,   7.997,\n",
      "         5.654,   9.27 ,   3.1  ]), <tf.Tensor 'inputs/y:0' shape=<unknown> dtype=float32>: array([ 1.7  ,  2.76 ,  2.09 ,  3.19 ,  1.694,  1.573,  3.366,  2.596,\n",
      "        2.53 ,  1.221,  2.827,  3.465,  1.65 ,  2.904,  2.42 ,  2.94 ,  1.3  ])}\n",
      "Training cost= 0.080417 w= 0.217136517167 b= 1.03496026993 \n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fb5f4089d50>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# compute\n",
    "# Start training\n",
    "with tf.Session() as sess:\n",
    "    values = {w:rng.randn(),b:rng.randn()}\n",
    "    # Fit all training data\n",
    "    t_start = time.time()\n",
    "    for epoch in range(training_epochs):\n",
    "        for (X, Y) in zip(train_X, train_Y):\n",
    "            values[x] = X\n",
    "            values[y] = Y\n",
    "            #compute the gradients\n",
    "            cost_np,grad_w_np,grad_b_np = sess.run([cost,grad_w,grad_b], feed_dict=values)\n",
    "            #update the parameters\n",
    "            values[w] -= learning_rate * grad_w_np\n",
    "            values[b] -= learning_rate * grad_b_np\n",
    "\n",
    "        #Display logs per epoch step\n",
    "        #print (epoch+1) % display_step\n",
    "        #print values\n",
    "        if (epoch+1) % display_step == 0:\n",
    "            c = sess.run(cost, feed_dict=values)\n",
    "            print \"Epoch:\", '%04d' % (epoch+1), \"cost=\", \"{:.9f}\".format(c), \\\n",
    "                \"W=\", sess.run(w,feed_dict=values), \"b=\", sess.run(b,feed_dict=values)\n",
    "\n",
    "    print \"Optimization Finished, spend time: {}!\".format(time.time()-t_start)\n",
    "    values[x] = train_X\n",
    "    values[y] = train_Y\n",
    "    print values\n",
    "    training_cost = sess.run(cost, feed_dict=values)\n",
    "    print \"Training cost=\", training_cost, \"w=\", sess.run(w,feed_dict=values), \"b=\", sess.run(b,feed_dict=values), '\\n'\n",
    "\n",
    "    #Graphic display\n",
    "    plt.plot(train_X, train_Y, 'ro', label='Original data')\n",
    "    plt.plot(train_X, sess.run(w,feed_dict=values) * train_X + sess.run(b,feed_dict=values), label='Fitted line')\n",
    "    plt.legend()\n",
    "    plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## linear regression v2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.summary.writer.writer.FileWriter at 0x7fb5d2d22a90>"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "# define the input by placeholder\n",
    "with tf.name_scope('inputs'):\n",
    "    x = tf.placeholder(tf.float32,name='x')\n",
    "    y = tf.placeholder(tf.float32,name='y')\n",
    "# define the weight\n",
    "# represent the learnable paramters by tf.placeholder\n",
    "with tf.variable_scope('params'):\n",
    "    w = tf.Variable(rng.randn(),name='w')\n",
    "    b = tf.Variable(rng.randn(),name='b')\n",
    "# construct inference model\n",
    "with tf.name_scope('inference'):\n",
    "    y_pred = tf.multiply(w,x) + b\n",
    "# Mean squared error as loss function\n",
    "with tf.name_scope('loss'):\n",
    "    cost = tf.reduce_sum(tf.pow(y_pred-y, 2))/(2*n_samples)\n",
    "with tf.name_scope('grads'):\n",
    "    grad_w,grad_b = tf.gradients(cost,[w,b])\n",
    "with tf.name_scope('update_params'):\n",
    "    new_w = w.assign(w-learning_rate*grad_w)\n",
    "    new_b = w.assign(b-learning_rate*grad_b)\n",
    "init = tf.global_variables_initializer()\n",
    "tf.summary.FileWriter('linear_model_v2',tf.get_default_graph())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "v3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 0050 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0100 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0150 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0200 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0250 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0300 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0350 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0400 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0450 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0500 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0550 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0600 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0650 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0700 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0750 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0800 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0850 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0900 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 0950 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Epoch: 1000 cost= 0.074008882 W= 1.13409 b= -0.629385\n",
      "Optimization Finished, spend time: 6.27559089661!\n",
      "Training cost= 10.4881 w= 1.13409 b= -0.629385 \n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fb5d376f410>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# compute\n",
    "# Start training\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    sess.run(init)\n",
    "    # Fit all training data\n",
    "    t_start = time.time()\n",
    "    values = {}\n",
    "    for epoch in range(training_epochs):\n",
    "        for (X, Y) in zip(train_X, train_Y):\n",
    "            values[x] = X\n",
    "            values[y] = Y\n",
    "            #compute the gradients\n",
    "            cost_np = sess.run([cost], feed_dict=values)\n",
    "            #update the parameters\n",
    "            #values[w] -= learning_rate * grad_w_np\n",
    "            #values[b] -= learning_rate * grad_b_np\n",
    "\n",
    "        #Display logs per epoch step\n",
    "        #print (epoch+1) % display_step\n",
    "        #print values\n",
    "        if (epoch+1) % display_step == 0:\n",
    "            c = sess.run(cost, feed_dict=values)\n",
    "            print \"Epoch:\", '%04d' % (epoch+1), \"cost=\", \"{:.9f}\".format(c), \\\n",
    "                \"W=\", sess.run(w), \"b=\", sess.run(b)\n",
    "\n",
    "    print \"Optimization Finished, spend time: {}!\".format(time.time()-t_start)\n",
    "    values[x] = train_X\n",
    "    values[y] = train_Y\n",
    "  \n",
    "    training_cost = sess.run(cost, feed_dict=values)\n",
    "    print \"Training cost=\", training_cost, \"w=\", sess.run(w,feed_dict=values), \"b=\", sess.run(b,feed_dict=values), '\\n'\n",
    "\n",
    "    #Graphic display\n",
    "    plt.plot(train_X, train_Y, 'ro', label='Original data')\n",
    "    plt.plot(train_X, sess.run(w,feed_dict=values) * train_X + sess.run(b,feed_dict=values), label='Fitted line')\n",
    "    plt.legend()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor(\"update_params/Assign:0\", shape=(), dtype=float32_ref) Tensor(\"update_params/Assign_1:0\", shape=(), dtype=float32_ref)\n",
      "name: \"update_params/group_deps\"\n",
      "op: \"NoOp\"\n",
      "input: \"^update_params/Assign\"\n",
      "input: \"^update_params/Assign_1\"\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.summary.writer.writer.FileWriter at 0x7fb5a934ae50>"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "# define the input by placeholder\n",
    "with tf.name_scope('inputs'):\n",
    "    x = tf.placeholder(tf.float32,name='x')\n",
    "    y = tf.placeholder(tf.float32,name='y')\n",
    "# define the weight\n",
    "# represent the learnable paramters by tf.placeholder\n",
    "with tf.variable_scope('params'):\n",
    "    w = tf.Variable(rng.randn(),name='w')\n",
    "    b = tf.Variable(rng.randn(),name='b')\n",
    "# construct inference model\n",
    "with tf.name_scope('inference'):\n",
    "    y_pred = tf.multiply(w,x) + b\n",
    "# Mean squared error as loss function\n",
    "with tf.name_scope('loss'):\n",
    "    cost = tf.reduce_sum(tf.pow(y_pred-y, 2))/(2*n_samples)\n",
    "with tf.name_scope('grads'):\n",
    "    grad_w,grad_b = tf.gradients(cost,[w,b])\n",
    "with tf.name_scope('update_params'):\n",
    "    new_w = w.assign(w,w-learning_rate*grad_w)\n",
    "    new_b = b.assign(b,b-learning_rate*grad_b)\n",
    "    print new_w,new_b\n",
    "    updates = tf.group(new_w,new_b)\n",
    "    print updates\n",
    "init = tf.global_variables_initializer()\n",
    "tf.summary.FileWriter('linear_model_v2',tf.get_default_graph())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.0016058\n",
      "Epoch: 0050 cost= 0.001605799 W= 0.373892 b= -0.0927243\n",
      "0.00121676\n",
      "Epoch: 0100 cost= 0.001216758 W= 0.366499 b= -0.0395425\n",
      "0.000900023\n",
      "Epoch: 0150 cost= 0.000900023 W= 0.359546 b= 0.0104763\n",
      "0.00064562\n",
      "Epoch: 0200 cost= 0.000645620 W= 0.353007 b= 0.0575203\n",
      "0.000444823\n",
      "Epoch: 0250 cost= 0.000444823 W= 0.346856 b= 0.101766\n",
      "0.000289999\n",
      "Epoch: 0300 cost= 0.000289999 W= 0.341072 b= 0.143381\n",
      "0.000174491\n",
      "Epoch: 0350 cost= 0.000174491 W= 0.335631 b= 0.18252\n",
      "9.24828e-05\n",
      "Epoch: 0400 cost= 0.000092483 W= 0.330514 b= 0.219332\n",
      "3.89099e-05\n",
      "Epoch: 0450 cost= 0.000038910 W= 0.325701 b= 0.253954\n",
      "9.36166e-06\n",
      "Epoch: 0500 cost= 0.000009362 W= 0.321175 b= 0.286518\n",
      "4.99794e-09\n",
      "Epoch: 0550 cost= 0.000000005 W= 0.316917 b= 0.317144\n",
      "7.51083e-06\n",
      "Epoch: 0600 cost= 0.000007511 W= 0.312913 b= 0.345949\n",
      "2.89944e-05\n",
      "Epoch: 0650 cost= 0.000028994 W= 0.309147 b= 0.373041\n",
      "6.19608e-05\n",
      "Epoch: 0700 cost= 0.000061961 W= 0.305605 b= 0.398522\n",
      "0.000104252\n",
      "Epoch: 0750 cost= 0.000104252 W= 0.302274 b= 0.422486\n",
      "0.000154013\n",
      "Epoch: 0800 cost= 0.000154013 W= 0.299141 b= 0.445026\n",
      "0.000209648\n",
      "Epoch: 0850 cost= 0.000209648 W= 0.296194 b= 0.466226\n",
      "0.000269785\n",
      "Epoch: 0900 cost= 0.000269785 W= 0.293422 b= 0.486164\n",
      "0.000333256\n",
      "Epoch: 0950 cost= 0.000333256 W= 0.290816 b= 0.504917\n",
      "0.000399064\n",
      "Epoch: 1000 cost= 0.000399064 W= 0.288364 b= 0.522554\n",
      "Optimization Finished, spend time: 7.63076090813!\n",
      "Training cost= 0.0817527 w= 0.288364 b= 0.522554 \n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fb5a946ec10>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# compute\n",
    "# Start training\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    sess.run(init)\n",
    "    # Fit all training data\n",
    "    t_start = time.time()\n",
    "    values = {}\n",
    "    for epoch in range(training_epochs):\n",
    "        for (X, Y) in zip(train_X, train_Y):\n",
    "            values[x] = X\n",
    "            values[y] = Y\n",
    "            #compute the gradients\n",
    "            cost_np,_ = sess.run([cost,updates], feed_dict=values)\n",
    "            #print(w_np,b_np)\n",
    "            #print cost_np\n",
    "            #update the parameters\n",
    "            #values[w] -= learning_rate * grad_w_np\n",
    "            #values[b] -= learning_rate * grad_b_np\n",
    "\n",
    "        #Display logs per epoch step\n",
    "        #print (epoch+1) % display_step\n",
    "        #print values\n",
    "        if (epoch+1) % display_step == 0:\n",
    "            c = sess.run(cost, feed_dict=values)\n",
    "            print(c)\n",
    "            print \"Epoch:\", '%04d' % (epoch+1), \"cost=\", \"{:.9f}\".format(c), \\\n",
    "                \"W=\", sess.run(w), \"b=\", sess.run(b)\n",
    "\n",
    "    print \"Optimization Finished, spend time: {}!\".format(time.time()-t_start)\n",
    "    values[x] = train_X\n",
    "    values[y] = train_Y\n",
    "  \n",
    "    training_cost = sess.run(cost, feed_dict=values)\n",
    "    print \"Training cost=\", training_cost, \"w=\", sess.run(w,feed_dict=values), \"b=\", sess.run(b,feed_dict=values), '\\n'\n",
    "\n",
    "    #Graphic display\n",
    "    plt.plot(train_X, train_Y, 'ro', label='Original data')\n",
    "    plt.plot(train_X, sess.run(w,feed_dict=values) * train_X + sess.run(b,feed_dict=values), label='Fitted line')\n",
    "    plt.legend()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [],
   "source": [
    "tf.reset_default_graph()\n",
    "# tf Graph Input\n",
    "X = tf.placeholder(\"float\")\n",
    "Y = tf.placeholder(\"float\")\n",
    "\n",
    "# Set model weights\n",
    "W = tf.Variable(rng.randn(), name=\"weight\")\n",
    "b = tf.Variable(rng.randn(), name=\"bias\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Construct a linear model\n",
    "pred = tf.add(tf.multiply(X, W), b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Mean squared error\n",
    "cost = tf.reduce_sum(tf.pow(pred-Y, 2))/(2*n_samples)\n",
    "# Gradient descent\n",
    "optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initialize the variables (i.e. assign their default value)\n",
    "init = tf.global_variables_initializer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 0050 cost= 0.293763399 W= 0.509838 b= -1.07071\n",
      "Epoch: 0100 cost= 0.268723488 W= 0.49436 b= -0.959364\n",
      "Epoch: 0150 cost= 0.246574596 W= 0.479802 b= -0.854638\n",
      "Epoch: 0200 cost= 0.226983175 W= 0.466111 b= -0.756141\n",
      "Epoch: 0250 cost= 0.209654212 W= 0.453233 b= -0.663503\n",
      "Epoch: 0300 cost= 0.194326237 W= 0.441122 b= -0.576374\n",
      "Epoch: 0350 cost= 0.180768371 W= 0.429731 b= -0.494428\n",
      "Epoch: 0400 cost= 0.168776065 W= 0.419017 b= -0.417355\n",
      "Epoch: 0450 cost= 0.158168808 W= 0.408941 b= -0.344866\n",
      "Epoch: 0500 cost= 0.148786604 W= 0.399464 b= -0.276688\n",
      "Epoch: 0550 cost= 0.140487984 W= 0.39055 b= -0.212565\n",
      "Epoch: 0600 cost= 0.133147866 W= 0.382167 b= -0.152256\n",
      "Epoch: 0650 cost= 0.126655579 W= 0.374282 b= -0.0955337\n",
      "Epoch: 0700 cost= 0.120913252 W= 0.366866 b= -0.0421848\n",
      "Epoch: 0750 cost= 0.115834273 W= 0.359891 b= 0.00799119\n",
      "Epoch: 0800 cost= 0.111342035 W= 0.353332 b= 0.055183\n",
      "Epoch: 0850 cost= 0.107368819 W= 0.347162 b= 0.0995681\n",
      "Epoch: 0900 cost= 0.103854656 W= 0.341359 b= 0.141313\n",
      "Epoch: 0950 cost= 0.100746587 W= 0.335901 b= 0.180576\n",
      "Epoch: 1000 cost= 0.097997658 W= 0.330768 b= 0.217503\n",
      "Optimization Finished, spend time: 7.76616692543!\n",
      "Training cost= 0.0979977 W= 0.330768 b= 0.217503 \n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fb5d2d22b10>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Start training\n",
    "with tf.Session() as sess:\n",
    "    t_start = time.time()\n",
    "    sess.run(init)\n",
    "\n",
    "    # Fit all training data\n",
    "    for epoch in range(training_epochs):\n",
    "        for (x, y) in zip(train_X, train_Y):\n",
    "            sess.run(optimizer, feed_dict={X: x, Y: y})\n",
    "\n",
    "        #Display logs per epoch step\n",
    "        if (epoch+1) % display_step == 0:\n",
    "            c = sess.run(cost, feed_dict={X: train_X, Y:train_Y})\n",
    "            print \"Epoch:\", '%04d' % (epoch+1), \"cost=\", \"{:.9f}\".format(c), \\\n",
    "                \"W=\", sess.run(W), \"b=\", sess.run(b)\n",
    "\n",
    "    print \"Optimization Finished, spend time: {}!\".format(time.time()-t_start)\n",
    "    training_cost = sess.run(cost, feed_dict={X: train_X, Y: train_Y})\n",
    "    print \"Training cost=\", training_cost, \"W=\", sess.run(W), \"b=\", sess.run(b), '\\n'\n",
    "\n",
    "    #Graphic display\n",
    "    plt.plot(train_X, train_Y, 'ro', label='Original data')\n",
    "    plt.plot(train_X, sess.run(W) * train_X + sess.run(b), label='Fitted line')\n",
    "    plt.legend()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Regression result"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
